package view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.WindowConstants;

import controller.Main;

import model.Observer;
import model.os.OS;
import model.os.OSProcess;

import view.tablecellrenderer.HardDiskViewCellRenderer;
import view.tablecellrenderer.RAMViewCellRenderer;
import view.util.OSProcessColor;

public class MainFrame extends JFrame implements Observer{
	
	private static final long serialVersionUID = -1355539783551828905L;
	
	private JTable ramTable;
	
	private JTable hardDiskTable;
	
	private JPanel framePanel;
	
	private JToolBar toolBar;
	
	private JPanel bottomPanel;
	
	public MainFrame() {
		
		setTitle("Page Replacement Algorithms");
		setSize(1024, 768);
		setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		setResizable(false);
		initializeComponents();
		pack();
		setVisible(true);
		
	}
	
	private void initializeComponents() {
		framePanel = new JPanel(new BorderLayout());
	
		JPanel centerPanel = new JPanel(new FlowLayout());
		toolBar = new JToolBar();
		toolBar.setPreferredSize(new Dimension(200,50));
		
		initializeRam(centerPanel);
		initializeHardDisk(centerPanel);
		initializeAlgorithmsPanel(toolBar);

		bottomPanel = new JPanel(new FlowLayout());
		initializeBottomPanel();
		
		framePanel.add(toolBar, BorderLayout.NORTH);
		framePanel.add(centerPanel, BorderLayout.CENTER);
		framePanel.add(bottomPanel, BorderLayout.SOUTH);
		
		add(framePanel);
	}
	
	private void initializeHardDisk(JPanel centerPanel) {
		JTabbedPane tabbedPane = new JTabbedPane();
		hardDiskTable = new JTable(new HardDiskView());
		hardDiskTable.setCellSelectionEnabled(false);
		hardDiskTable.setColumnSelectionAllowed(false);
		hardDiskTable.setRowSelectionAllowed(false);
		hardDiskTable.setDefaultRenderer(Object.class, new HardDiskViewCellRenderer());
		tabbedPane.add("Hard Disk", new JScrollPane(hardDiskTable));
		centerPanel.add(tabbedPane);
	}
	
	private void initializeRam(JPanel centerPanel) {
		JTabbedPane tabbedPane = new JTabbedPane();
		ramTable = new JTable(new RAMView());
		ramTable.setRowHeight(50);
		ramTable.setCellSelectionEnabled(false);
		ramTable.setColumnSelectionAllowed(false);
		ramTable.setRowSelectionAllowed(false);
		ramTable.setDefaultRenderer(Object.class, new RAMViewCellRenderer());
		tabbedPane.add("RAM", new JScrollPane(ramTable));
		centerPanel.add(tabbedPane);
	}
	
	private void initializeAlgorithmsPanel(JToolBar panel){
		JLabel algorithmLabel = new JLabel("Page Replacement Algorithm   ");
		JComboBox algorithmsComboBox = new JComboBox(new String[] { "FIFOW2C", "LRU" }) {
			private static final long serialVersionUID = 8740158588640224556L;

			public void actionPerformed(ActionEvent e) {
				 JComboBox cb = (JComboBox)e.getSource();
			             OS.getInstance().setPageReplacementStrategy((String)cb.getSelectedItem());
			}
		};
		algorithmsComboBox.setMaximumSize(new Dimension(100, 20));
		algorithmsComboBox.addActionListener(algorithmsComboBox);
		panel.add(algorithmLabel);
		panel.add(algorithmsComboBox);
	}
	
	private void initializeBottomPanel(){
		addReferenceLabel(Color.GREEN, "Pages in RAM");
		
		OSProcessColor[] colors = OSProcessColor.values();
		for (int i = 0; i < Main.PROCESSES; i++) {
			addReferenceLabel(colors[i].getColor(), "Process" + i);
		}
	}
	
	private void addReferenceLabel(Color color, String description) {
		JLabel colorLabel = new JLabel("");
		colorLabel.setOpaque(true);
		colorLabel.setPreferredSize(new Dimension(20,20));
		colorLabel.setBackground(color);
		bottomPanel.add(colorLabel);
		JLabel descriptionLabel = new JLabel(description);
		bottomPanel.add(descriptionLabel);
	}
	
	public JPanel getBottomPanel() {
		return bottomPanel;
	}
	
	public void update() {
		ramTable.repaint();
		hardDiskTable.repaint();
	}

}
